package com.handle.common.redis.util;

import lombok.AllArgsConstructor;
import org.redisson.api.RBucket;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.concurrent.TimeUnit;

/**
 * @author zhangqing
 * @version V1.0
 * @description redisson工具类
 * @date 29/12/2020 10:12 AM
 */
@Component
@AllArgsConstructor
public class RedissonUtil {
    private final RedissonClient redissonClient;

    public <T> void setValue(String key, T data, long timeOut, TimeUnit timeUnit) {
        RBucket<T> rBucket = redissonClient.getBucket(key);
        if (rBucket.isExists()) {
            //key值已经存在
            rBucket.delete();
        }
        rBucket.set(data);
        if (!StringUtils.isEmpty(timeUnit)) {
            rBucket.expire(timeOut, timeUnit);
        }
    }

    public <T> T getValue(String key) {
        RBucket<T> rBucket = redissonClient.getBucket(key);
        if (rBucket.isExists()) {
            //key值已经存在
            return rBucket.get();
        }
        return null;
    }

    public <T> boolean delKey(String key) {
        RBucket<T> rBucket = redissonClient.getBucket(key);
        return rBucket.delete();
    }

    /**
     * 按名称返回锁实例。
     * @param name 锁名称
     * @return 锁对象
     */
    public RLock getLock(String name){
        return redissonClient.getLock(name);
    }

    /**
     * 立即获取锁,看门狗机制生效
     * @param lock 锁对象
     * @return {@code true} 如果获得了锁,否则 {@code false}
     */
    public Boolean tryLock(RLock lock){
        return lock.tryLock();
    }

    /**
     * 指定等待时间获取锁,看门狗机制生效
     * @param lock 锁对象
     * @param time 等待获取锁最大时间
     * @param unit 时间单位
     * @return {@code true}如果获得了锁，否则{@code false}
     * 如果在获得锁之前等待时间已经过去
     */
    public Boolean tryLock(RLock lock,long time,TimeUnit unit){
        try {
            return lock.tryLock(time,unit);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return Boolean.FALSE;
    }

    /**
     * 指定等待时间获取锁,如果获取到锁设置锁过期时间,此方式看门狗机制失效
     * @param lock 锁对象
     * @param waitTime 等待获取锁时间
     * @param leaseTime 锁过期时间
     * @param unit 单位
     * @return <code>true</code> 如果锁定成功,
     *      否则 <code>false</code> 如果锁已经设置。
     */
    public Boolean tryLock(RLock lock,long waitTime, long leaseTime, TimeUnit unit){
        try {
            return lock.tryLock(waitTime,leaseTime,unit);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return Boolean.FALSE;
    }

    /**
     * 释放锁
     * @param lock 锁对象
     */
    public void unlock(RLock lock){
        lock.unlock();
    }


}
